package com.example.demo.mapper;

import com.example.demo.model.User;
import com.example.demo.model.UserCredit;
import org.apache.ibatis.annotations.*;

import java.time.LocalDateTime;
import java.util.List;

@Mapper
public interface UserMapper {
    @Select("SELECT id, username, password, email, role, " +
            "is_banned AS banned, ban_reason, ban_time, ban_expiry " +
            "FROM user WHERE username = #{username}")
    User findByUsername(String username);

    @Select("SELECT id, username, password, email, role, " +
            "is_banned AS banned, ban_reason, ban_time, ban_expiry " +
            "FROM user WHERE id = #{id}")
    User selectUserById(Long id);

    @Select("SELECT * FROM user WHERE email = #{email}")
    @Results({
            @Result(property = "id", column = "id"),
            @Result(property = "username", column = "username"),
            @Result(property = "email", column = "email"),
            @Result(property = "role", column = "role"),
            @Result(property = "banned", column = "is_banned"),
            @Result(property = "banReason", column = "ban_reason"),
            @Result(property = "banTime", column = "ban_time"),
            @Result(property = "banExpiry", column = "ban_expiry"),
            @Result(property = "isVip", column = "is_vip"),
            @Result(property = "vipExpiry", column = "vip_expiry"),
            @Result(property = "upload", column = "upload"),
            @Result(property = "download", column = "download"),
            @Result(property = "shareRating", column = "share_rating")

    })
    User findByEmail(String email);

    @Select("SELECT * FROM user")
    @Results({
            @Result(property = "id", column = "id"),
            @Result(property = "username", column = "username"),
            @Result(property = "email", column = "email"),
            @Result(property = "banned", column = "is_banned"),
            @Result(property = "banReason", column = "ban_reason"),
            @Result(property = "banTime", column = "ban_time"),
            @Result(property = "banExpiry", column = "ban_expiry")
    })
    List<User> findAllUsers();

    @Update("UPDATE user SET " +
            "is_banned = #{banned}, " +
            "ban_reason = #{banReason}, " +
            "ban_time = #{banTime}, " +
            "ban_expiry = #{banExpiry} " +
            "WHERE id = #{id}")
    int updateBanStatus(User user);

    @Select("SELECT is_banned " +
            "FROM user WHERE email = #{email}")
    @Result(property = "banned", column = "is_banned")
    boolean getBanStatusByEmail(String email);

    @Update("UPDATE user SET role = #{role} WHERE id = #{userId}")
    void updateUserRole(Long userId, String role);

    @Insert("INSERT INTO user (username, password, email, role) VALUES (#{username}, #{password}, #{email}, #{role})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    void insertUser(User user);

    @Update("UPDATE user SET password = #{newPassword} WHERE id = #{userId}")
    void updatePassword(Long userId, String newPassword);

    @Update("UPDATE user SET " +
            "username = #{username}, " +
            "password = #{password}, " +
            "email = #{email}, " +
            "role = #{role}, " +
            "is_banned = #{banned}, " +
            "ban_reason = #{banReason}, " +
            "ban_time = #{banTime}, " +
            "ban_expiry = #{banExpiry} " +
            "WHERE id = #{id}")
    void updateUser(User user);

    @Select("SELECT * FROM user WHERE id = #{id}")
    @Results({
            @Result(property = "id", column = "id"),
            @Result(property = "username", column = "username"),
            @Result(property = "password", column = "password"),
            @Result(property = "email", column = "email"),
            @Result(property = "role", column = "role"),
            @Result(property = "banned", column = "is_banned"),
            @Result(property = "banReason", column = "ban_reason"),
            @Result(property = "banTime", column = "ban_time"),
            @Result(property = "banExpiry", column = "ban_expiry")
    })
    User getUserById(Long id);

    @Select("SELECT * FROM user WHERE id = #{id}")
    @Results({
            @Result(property = "id", column = "id"),
            @Result(property = "username", column = "username"),
            @Result(property = "password", column = "password"),
            @Result(property = "role", column = "role"),
            @Result(property = "isVip", column = "is_vip"),
            @Result(property = "vipExpiry", column = "vip_expiry"),
            @Result(property = "upload", column = "upload"),
            @Result(property = "download", column = "download"),
            @Result(property = "shareRating", column = "share_rating")
    })
    User findById(@Param("id") Long id);

    @Update("UPDATE user SET is_vip = #{isVip}, vip_expiry = #{vipExpiry} WHERE id = #{id}")
    void updateVipStatus(@Param("id") Long id, @Param("isVip") boolean isVip, @Param("vipExpiry") LocalDateTime vipExpiry);

    @Select("SELECT * FROM user WHERE is_vip = true")
    @Results({
            @Result(property = "id", column = "id"),
            @Result(property = "isVip", column = "is_vip"),
            @Result(property = "vipExpiry", column = "vip_expiry")
    })
    List<User> findAllWithVip();

    @Select("SELECT * FROM user_credit WHERE user_id = #{userId}")
    @Results({
            @Result(property = "id", column = "id"),
            @Result(property = "userId", column = "user_id"),
            @Result(property = "balance", column = "balance")
    })
    UserCredit findBalanceByUserId(@Param("userId") Long userId);

    @Update("UPDATE user SET username = #{username} " +
            "WHERE id = #{id}")
    int updateUserName(Long id, String username);

    @Select("SELECT email FROM user WHERE username = #{username}")
    String findEmailByUsername(String username);

    @Update("UPDATE user SET upload = #{upload}, download = #{download} WHERE id = #{id}")
    void updateUploadDownload(@Param("id") Long id, @Param("upload") String upload, @Param("download") String download);

    @Update("UPDATE user SET share_rating = #{shareRating} WHERE id = #{id}")
    void updateShareRating(@Param("id") Long id, @Param("shareRating") double shareRating);
    @Select("SELECT password FROM user WHERE email = #{email}")
    String findPasswordByEmail(String email);

}